#ifndef MESSAGE_QUEUE_H_
#define MESSAGE_QUEUE_H_

#include "../utils/Logger.h"
#include <sys/types.h>
#include <sys/msg.h>
#include <sys/ipc.h>
#include <stdio.h>
#include <string>

template <class T>
class Message_Queue
{
	private:
		key_t	clave;
		int		id;

	public:
		Message_Queue( const std::string& file, const char key );
		virtual ~Message_Queue();
		bool write_msg( const T& buff ) const;
		int read_msg( const int type, T* buffer ) const;
		int destroy() const;
};

template <class T>
Message_Queue<T>::Message_Queue( const std::string& file, const char key )
{
	this->clave = ftok ( file.c_str(), key );
	if( this->clave == -1 ){
		Logger::getInstance().logMessage( Logger::ERROR, "Error en ftok" );
		perror("ftok");
	}

	this->id = msgget( this->clave, 0777|IPC_CREAT );
	if( this->id == -1 ){
		Logger::getInstance().logMessage( Logger::ERROR, "Error al crear cola" );
		perror("msgget");
	}
}

template <class T>
Message_Queue<T>::~Message_Queue()
{
}

template <class T>
int Message_Queue<T>::destroy() const
{
	int result = msgctl( this->id, IPC_RMID, NULL );
	if( result == -1 )
	{
		Logger::getInstance().logMessage( Logger::ERROR, "FALLO AL BORRAR LA COLA : Error al borrar la cola" );
		//TODO fix include
		/*if( errno ==  EIDRM )
		{
			Logger::getInstance().logMessage( Logger::ERROR, "La cola no existe" );
		}*/
	}
	return result;
}

template <class T>
bool Message_Queue<T>::write_msg( const T& buff ) const
{
	bool sent = true;
	int result = msgsnd( this->id, static_cast<const void*>(&buff), sizeof(T)-sizeof(long), 0 );
	if( result == -1 ) {
		sent = false;
		Logger::getInstance().logMessage( Logger::ERROR, "FALLO AL ESCRIBIR LA COLA : Error en envio de mensaje" );
		perror("msgsnd");
	}
	return sent;
}

template <class T>
int Message_Queue<T>::read_msg( const int type, T* buffer ) const
{
	int result = msgrcv( this->id, static_cast<void *>(buffer), sizeof(T)-sizeof(long), type, 0 );
	if(  result == -1 ){
		Logger::getInstance().logMessage( Logger::ERROR, "FALLO AL LEER LA COLA :Error al recibir mensaje" );
		perror("msgrcv");
	}
	return result;
}

#endif /* MESSAGE_QUEUE_H_ */
